﻿using System;
using System.Web.Mvc;
using PagedList;

using SIG.Service.Identity;
using SIG.Model.Identity;
using SIG.Infrastructure.Configs;
using SIG.Model.ViewModel.Identity;
using SIG.WebMVC.Filters;
using AutoMapper;
using SIG.ViewModel;
using System.Threading.Tasks;
using SIG.ViewModel.Identity;
using System.Linq;
using SIG.Resources.Admin;
using SIG.InputModel.Admin.Identity;
using SIG.ViewModel.Admin.Identity;
using System.Collections.Generic;
using System.Xml.Linq;
using SIG.Infrastructure.Helper;

namespace SIG.WebMVC.Areas.Admin.Controllers
{
    [SIGAuth]
    public class UserController : BaseController
    {


        IUserService _userService;
        IRoleService _roleService;
        IMapper _mapper;
      
        public UserController(IUserService UserService,  IRoleService roleService, IMapper mapper)
        {
            _userService = UserService;
            _roleService = roleService;
            _mapper = mapper;

    }

        // GET: User
        //  [CustomAuthorize(Roles = "Admin")]
        public ActionResult Index(int? page, string keyword, DateTime? startDate, DateTime? endDate, int? roleId)
        {
            var userListVM = new UserListVM
            {
                StartDate = startDate,
                EndDate = endDate,
                Keyword = keyword,
                RoleId = roleId,           
                PageIndex = (page ?? 1) - 1,
                PageSize = SettingsManager.User.PageSize,
                SetPasswordVM = new SetPasswordVM()
            };
            
            int totalCount;

            var users = _userService.GetPagedElements(userListVM.PageIndex, userListVM.PageSize, userListVM.Keyword,
                userListVM.StartDate, userListVM.EndDate,userListVM.RoleId,out totalCount);

            userListVM.TotalCount = totalCount;

            var userList = _mapper.Map<IList<User>, IList<UserVM>>(users);

            userListVM.Users = new StaticPagedList<UserVM>(userList, userListVM.PageIndex+1, userListVM.PageSize, userListVM.TotalCount);
            // ViewBag.OnePageOfUsers = usersAsIPagedList;
            ViewBag.PageSizes = new SelectList(Site.PageSizes());

            var roleList = _roleService.FindBy(m=>m.Id!=SettingsManager.Role.Founder).ToList();
            var roles = new SelectList(roleList, "Id", "RoleName");
            ViewBag.Roles = roles;

            return View(userListVM);

        }


        [HttpPost]
        public JsonResult PageSizeSet(int pageSize)
        {
            try
            {
                var xmlFile = Server.MapPath("~/Config/UserSettings.config");
                XDocument doc = XDocument.Load(xmlFile);

                var item = doc.Descendants("Settings").FirstOrDefault();
                item.Element("PageSize").SetValue(pageSize);
                doc.Save(xmlFile);

                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            catch (Exception ex)
            {
                AR.Setfailure(ex.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
        }

        // GET: User/Details/5
        [HttpGet]
        public ActionResult Details(Guid id)
        {
            //if (id == null)
            //{
            //    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            //}
            User user = _userService.GetById(id);
            if (user == null)
            {
                return HttpNotFound();
            }
            return PartialView("_Detail",user);
        }

        // GET: User/Create
        public ActionResult Create()
        {
            RegisterIM vm = new RegisterIM();
            return PartialView("_UserCreate", vm);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public JsonResult Create(RegisterIM model)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

          
            var result = _userService.Register(model.UserName,model.Email,model.Password,model.DisplayName);
            if (result == 1)
            {
                AR.Setfailure(Messages.CannotRegisterEmail);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            if (result == 2)
            {
                AR.Setfailure(Messages.CannotRegisterUserName);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }


            int count;
            int pageSize = SettingsManager.User.PageSize;
            var list = _userService.GetPagedElements(0, pageSize, string.Empty,null,null,null, out count);
            List<UserVM> userList = _mapper.Map<List<User>, List<UserVM>>(list);
            AR.Data = RenderPartialViewToString("_UserList", userList);

            AR.SetSuccess(string.Format(Messages.AlertCreateSuccess, EntityNames.User));
            return Json(AR, JsonRequestBehavior.DenyGet);



        }


        public async Task<JsonResult> IsUserNameUnique(string UserName)
        {
            var user = await _userService.GetUserByName(UserName);

            return user == null
                ? Json(true, JsonRequestBehavior.AllowGet)
                : Json(false, JsonRequestBehavior.AllowGet);
        }

        public async Task<JsonResult> IsEmailUnique(string Email)
        {
            var user = await _userService.GetUserByEmail(Email);

            return user == null
                ? Json(true, JsonRequestBehavior.AllowGet)
                : Json(false, JsonRequestBehavior.AllowGet);
        }

        // GET: Users/Edit/5
        public ActionResult Edit(Guid? id)
        {
            ProfileIM Profiles = new ProfileIM();
            if (id == null)
            {               
                return PartialView("_UserEdit", Profiles);
            }
            var user = _userService.GetById(id);
            if (user == null)
            {
                return HttpNotFound();
            }

            Profiles = _mapper.Map<ProfileIM>(user);
            return PartialView("_UserEdit", Profiles);
            
        }

     
        [HttpPost]
        [ValidateAntiForgeryToken]
        public JsonResult Edit([Bind(Include = "Id,Email,RealName,Birthday,IsActive,Gender,QQ,Mobile")] ProfileIM profile)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            var user = _userService.GetById(profile.Id);
            if (user == null)
            {
                AR.Setfailure("不存在此用户！");
                return Json(AR, JsonRequestBehavior.DenyGet);
               // return Json(false, JsonRequestBehavior.DenyGet);
            }
            try
            {
                user.Email = profile.Email;
                user.RealName = profile.RealName;
                user.IsActive = profile.IsActive;
                //user.DepartmentId = profile.DepartmentId;
                //user.PositionId = profile.PositionId;
                user.QQ = profile.QQ;
                user.Mobile = profile.Mobile;
                user.Gender = profile.Gender;
                user.Birthday = profile.Birthday;

                _userService.Update(user);

                var userVM = _mapper.Map<UserVM>(user);

                AR.Id = user.Id;
                AR.Data = RenderPartialViewToString("_UserItem", userVM);


                AR.SetSuccess(string.Format(Messages.AlertUpdateSuccess,EntityNames.User));
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            catch(Exception ex)
            {
                AR.Setfailure(ex.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

        }
        public JsonResult IsEmailUniqueAtEdit(string email, Guid id)
        {
            var result = _userService.IsEmailUniqueAtEdit(email, id);

            return result
                ? Json(true, JsonRequestBehavior.AllowGet)
                : Json(false, JsonRequestBehavior.AllowGet);
        }


        [HttpGet]
        public PartialViewResult SetRole(Guid id)
        {
          
            var user = _userService.GetById(id);
            SetUserRoles vm = new SetUserRoles
            {
                UserId = id,
                RoleIds = user.Roles.Select(r=>r.Id).ToArray(),
                Roles = _roleService.GetAll().Where(r=>r.Id!=SettingsManager.Role.Founder)
            };
            
            return PartialView("_SetRole", vm);
        }


        [HttpPost]
        public JsonResult SetRole(Guid UserId, int[] RoleId)
        {
            try
            {
                var user = _userService.GetById(UserId);

                var roles = _roleService.FindBy(r => RoleId.Contains(r.Id));
                user.Roles.Clear();
                foreach (Role r in roles)
                {
                    user.Roles.Add(r);
                }

                _userService.Update(user);

                if(User.UserId == user.Id)
                    _userService.SetUserCookies(true, user);

                var userVM = _mapper.Map<UserVM>(user);
                AR.Id = user.Id;
                AR.Data = RenderPartialViewToString("_UserItem", userVM);

                AR.SetSuccess(Messages.AlertActionSuccess);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }catch(Exception ex)
            {
                AR.Setfailure(ex.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }          


        }

        [HttpGet]
        public ActionResult SetPassword(Guid id)
        {
            SetPasswordVM model = new SetPasswordVM
            {
                UserId = id
            };           
            return PartialView("_SetPassword",model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public JsonResult SetPassword(SetPasswordVM model)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            
            var result = _userService.SetPassword(model.UserId, model.NewPassword);
            if (result)
            {

                AR.SetSuccess(Messages.AlertActionSuccess);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            AR.Setfailure(Messages.AlertActionFailure);
            return Json(AR, JsonRequestBehavior.DenyGet);
          
        }


        [HttpPost]
        public JsonResult IsActive(Guid id)
        {
            var user = _userService.GetById(id);
            if (user != null)
            {
                user.IsActive = !user.IsActive;
                _userService.Update(user);

                var userVM = _mapper.Map<UserVM>(user);

                AR.Id = user.Id;
                AR.Data = RenderPartialViewToString("_UserItem", userVM);

                AR.SetSuccess(Messages.AlertActionSuccess);
                return Json(AR, JsonRequestBehavior.DenyGet);              

            }
            AR.Setfailure(Messages.AlertActionFailure);
            return Json(AR, JsonRequestBehavior.DenyGet);
           
        }


        // POST: Users/Delete/5
        [HttpPost, ActionName("Delete")]
        //[ValidateAntiForgeryToken]
        public JsonResult DeleteConfirmed(Guid id)
        {
            User user = _userService.GetById(id);  
           
            if (user == null)
            {               
                AR.Setfailure("未找到此用户！");
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            if (user.Id.ToString() == SettingsManager.User.Founder)
            {
                AR.Status = Model.Enums.Status.Warning;
                AR.Setfailure("创始人帐号，不可以删除！");             
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            _userService.Delete(user);
            return Json(AR, JsonRequestBehavior.DenyGet);          
        }

        
    }
}